package net.yla.smartbus.module.ba.right.account.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.vip.vjtools.vjkit.collection.ListUtil;
import com.vip.vjtools.vjkit.mapper.BeanMapper;
import net.yla.smartbus.core.api.RequestCode;
import net.yla.smartbus.core.base.BaseService;
import net.yla.smartbus.core.base.PageBean;
import net.yla.smartbus.core.exception.AppException;
import net.yla.smartbus.core.util.*;
import net.yla.smartbus.core.util.mini.ChineseUtils;
import net.yla.smartbus.module.ba.right.account.dto.AccountsDTO;
import net.yla.smartbus.module.ba.right.account.entity.LoginLogsDO;
import net.yla.smartbus.module.ba.right.account.mapper.LoginLogsMapper;
import net.yla.smartbus.module.ba.right.account.query.AccountOfQuery;
import net.yla.smartbus.module.ba.right.account.service.LoginLogsService;
import net.yla.smartbus.module.ba.right.account.service.LoginTracesService;
import net.yla.smartbus.module.ba.right.admin.dto.AdminDTO;
import net.yla.smartbus.module.ba.right.admin.entity.AdminDO;
import net.yla.smartbus.module.ba.right.admin.query.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import net.yla.smartbus.module.ba.right.account.mapper.AccountsMapper;
import net.yla.smartbus.module.ba.right.account.entity.AccountsDO;
import net.yla.smartbus.module.ba.right.account.service.AccountsService;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @Date: 2020-08-29 11:02
 * @Author: Being Nobody
 * @Version: 1.0
 */
@Service
public class AccountsServiceImpl extends BaseService implements AccountsService {

    @Resource
    private AccountsMapper accountsMapper;
    @Resource
    private LoginTracesService loginTracesService;
    @Resource
    private LoginLogsService loginLogsService;
    @Resource
    private LoginLogsMapper loginLogsMapper;
    @Autowired
    AccountsMapper accountMapper;


    @Override
    public int deleteByPrimaryKey(Integer accountId) {
        return accountsMapper.deleteByPrimaryKey(accountId);
    }

    @Override
    public int insert(AccountsDO record) {
        return accountsMapper.insert(record);
    }

    @Override
    public int insertSelective(AccountsDO record) {
        return accountsMapper.insertSelective(record);
    }

    @Override
    public AccountsDO selectByPrimaryKey(Integer accountId) {
        return accountsMapper.selectByPrimaryKey(accountId);
    }

    @Override
    public int updateByPrimaryKeySelective(AccountsDO record) {
        return accountsMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(AccountsDO record) {
        return accountsMapper.updateByPrimaryKey(record);
    }

    @Override
    public AccountsDO selectByLoginId(String loginId) {
        return accountsMapper.selectByLoginId(loginId);
    }

    @Override
    public List<JSONObject> account(AdminQuery query) {
        // 分页 查询的字段
        String sortOrder = super.orderBy(query.getSort(), query.getOrder());
//        PageHelper.offsetPage(query.getOffset(), query.getCount(), sortOrder.isEmpty() ? "accountId" : sortOrder);
        List<AccountsDO> list = accountsMapper.account(query);
        List<JSONObject> list1 = this.pageOfAccount(list, query.getFields());
        return list1;
    }

    @Override
    public int saveSelective(AccountOfQuery query) {
        // 校验参数
        this.checkParam(query);
        // loginId不能重复
        AccountsDO admin1 = accountsMapper.checkLoginId(query.getId(), query.getLoginId());
        if (admin1 != null) {
            throw new AppException("用户名已经存在", RequestCode.Form_Validate_Error);
        }
        // 添加
        return query.getId() == null ? this.add(query) : this.update(query);
    }

    private int update(AccountOfQuery query) {
        // 修改默认值
        super.updateSetDefaultValue(query);
        JSONObject jsonObject = DtoUtils.asDtoJsonForOnly(query);
        AccountsDO accountsDO = JSON.toJavaObject(jsonObject, AccountsDO.class);
        if (StringUtils.isNotEmpty(query.getLoginPwd())) {
            //修改密码
            accountsDO.setLoginPwd(ShiroUtils.md5(query.getLoginId(), query.getLoginPwd()));
        }
        // 正常更新
        return accountsMapper.updateByPrimaryKeySelective(accountsDO);
    }

    private int add(AccountOfQuery query) {
        if (query.getEmpId() == null) {
            throw new AppException("雇员ID不能为空", RequestCode.Form_Validate_Error);
        }
        AccountsDO aDo = accountsMapper.selectByEmpId(query.getEmpId());
        if (aDo != null) {
            throw new AppException("empId已经存在", RequestCode.Form_Validate_Error);
        }
        // 修改密码
        String s = ShiroUtils.md5(query.getLoginId(), query.getLoginPwd());
        // 修改IP？
        // 修改别名 数据库别名不允许为空
        query.setNickname(ChineseUtils.getPinYinHeadChar(query.getLoginId()));
        AccountsDO accountsDO = new AccountsDO();
        BeanUtils.copyProperties(query, accountsDO);
        accountsDO.setEmployeeId(query.getEmpId());
        accountsDO.setLoginPwd(s);
        return accountsMapper.insertSelective(accountsDO);
    }

    private void checkParam(AccountOfQuery query) {
        // 账户名
        if (StringUtils.isEmpty(query.getLoginId())) {
            throw new AppException("用户名为空", RequestCode.Form_Validate_Error);
        }
        // 密码
        if (StringUtils.isEmpty(query.getLoginPwd())) {
            throw new AppException("密码为空", RequestCode.Form_Validate_Error);
        }
    }

    private List<JSONObject> pageOfAccount(List<AccountsDO> list, List<String> fields) {
        List<JSONObject> result = null;
        if (ListUtil.isNotEmpty(list)) {
            result = new ArrayList<>(list.size());
            for (AccountsDO accountsDO : list) {
                JSONObject object = PojoJsonUtil.writeJsonByField(accountsDO, fields);
                // TODO 当前用户含有的角色
                result.add(object);
            }
        }
        return result;
    }

    @Override
    public int count(AdminCount query) {
        return accountsMapper.countByQuery(query);
    }

    /**
     * 批量删除账号
     *
     * @param accountIds
     * @return
     */
    @Override
    public int deleteByList(List<Integer> accountIds) {
        for (Integer accountId : accountIds) {
            if (this.del(accountId) < 0) {
                throw new AppException("删除账号失败", RequestCode.Form_Validate_Error);
            }
        }
        return 1;
    }

    @Override
    public AccountsDO record(AdminQuery query) {
        return null;
    }

    @Override
    public int ipOfCount(IPCount count) {
        return loginTracesService.ipOfCount(count);
    }

    @Override
    public List<JSONObject> ipOfQuery(IPQuery query) {
        // 分页
        String sortOrder = super.orderBy(query.getSort(), query.getOrder());
//        PageHelper.offsetPage(query.getOffset(), query.getCount(), sortOrder.isEmpty() ? "traceId" : sortOrder);
        List<JSONObject> list = loginTracesService.ipOfQuery(query);
        return list;
    }

    @Override
    public int logOfCount(LogCount query) {
        long ip = 0;
        if (StringUtils.isNotEmpty(query.getIp())) {
            ip = IPUtil.ipv4ToLong(query.getIp());
        }
        return loginLogsService.logOfCount(query, ip);
    }

    @Override
    public PageBean<JSONObject> logOfQuery(LogQuery query) {
        long ip = IPUtil.ipv4ToLong(query.getIp());
        return loginLogsService.logOfQuery(query, ip);
    }

    @Override
    public JSONObject account(Integer id) {
        AccountsDO accountsDO = accountsMapper.selectByPrimaryKey(id);
        JSONObject jsonObject = null;
        if (accountsDO != null) {
            jsonObject = DtoUtils.asDtoJsonForOnly(accountsDO);
        }

        return jsonObject;
    }

    @Override
    public int del(Integer id) {
        if (id == null) {
            throw new AppException("标识号不能为空", RequestCode.Operate_Tip);
        }
        return accountsMapper.del(id);
    }

    @Override
    public JSONObject ipOfView(Integer traceId) {
        return loginTracesService.ipOfView(traceId);
    }

    @Override
    public JSONObject logOfView(Integer logId) {
        return loginLogsService.logOfView(logId);
    }

    //导出账号
    @Override
    public void export(AdminQuery query, HttpServletResponse response) {
        ExcelData data = new ExcelData();
        List<AccountsDO> accountDOList = accountsMapper.account(query);
        data.setName("账号信息");
        List<String> titles = new LinkedList<>();
        titles.add("账号名称");
        titles.add("分组");
        titles.add("状态");
        titles.add("角色种类");
        titles.add("邮箱");
        titles.add("手机号");
        titles.add("限期");
        data.setTitles(titles);
        List<List<Object>> rows = new LinkedList<>();
        List<Object> row = null;
        if (accountDOList != null) {
            for (AccountsDO accountDO : accountDOList) {
                row = new LinkedList<>();
                row.add(accountDO.getLoginId());
                /*row.add(accountDTO.getGroupId);*/
                row.add(accountDO.getState());
                /* row.add();*/
                row.add(accountDO.getEmail());
                row.add(accountDO.getPhone());
                /*row.add();*/
                rows.add(row);
            }
        }
        data.setRows(rows);
        ExcelUtils.exportExcel(response, "设备信息导出.xls", data);

    }

    //导出日志
    @Override
    public void exportLog(LogQuery query, Long ip, HttpServletResponse response) {
        ExcelData data = new ExcelData();
        List<LoginLogsDO> LoginDOList = loginLogsMapper.logOfQuery(query, ip);
        data.setName("日志信息");
        List<String> titles = new LinkedList<>();
        titles.add("账号");
        titles.add("状态");
        titles.add("ip");
        titles.add("登录区域");
        titles.add("行为描述");
        titles.add("时间");
        data.setTitles(titles);
        List<List<Object>> rows = new LinkedList<>();
        List<Object> row = null;
        if (LoginDOList != null) {
            for (LoginLogsDO loginLogsDO : LoginDOList) {
                row = new LinkedList<>();
                row.add(loginLogsDO.getAccountId());
                row.add(loginLogsDO.getLoginState());
                row.add(loginLogsDO.getForm());
                row.add(loginLogsDO.getLogId());
                row.add(loginLogsDO.getForm());
                row.add(loginLogsDO.getCreationTime());
                rows.add(row);
            }
        }
        data.setRows(rows);
        ExcelUtils.exportExcel(response, "日志信息导出.xls", data);
    }

    //删除账号
    @Override
    public int delLog(Integer id) {
        if (id == null) {
            throw new AppException("标识号不能为空", RequestCode.Operate_Tip);
        }
        return loginLogsMapper.delLog(id);
    }

    //批量删除账号
    @Override
    public int deleteByLogList(List<Integer> ids) {
        for (Integer id : ids) {
            if (this.delLog(id) < 0) {
                throw new AppException("删除账号失败", RequestCode.Form_Validate_Error);
            }
        }
        return 1;
    }

    /**
     * 分组名
     *
     * @param query
     * @return
     */
    public List<JSONObject> get(AdminQuery query) {
        List<AccountsDO> accountsDOList = accountMapper.account(query);
        List<JSONObject> jsonObjects = new LinkedList<>();
        /*for (AccountsDO accountsDO : accountsDOList) {
            JSONObject jsonObject = DtoUtils.asDtoJsonForOnly(accountsDO);
            EmployeeDO emp = employeeMapper.findOne(accountsDO.getEmployeeId());
            if (emp != null) {
                GroupEntity group = groupMapper.view(emp.getGroupId());
                if (group != null) {
                    jsonObject.put("groupName", group.getName());
                } else {
                    jsonObject.put("groupName", "");
                }
            } else {
                jsonObject.put("groupName", "");
            }
            jsonObjects.add(jsonObject);
        }*/
        return jsonObjects;
    }
}
